package org.example.back.service.advice;

import org.example.back.entity.health.ChronicDisease;
import org.example.back.mapper.advice.ChronicDiseaseAdviceMapper;
import org.example.back.mapper.health.ChronicDiseaseMapper;
import org.example.back.service.healthassistant.HealthAssistantService;
import org.example.back.entity.user.UserProfile;
import org.example.back.service.user.UserProfileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Date;

@Service
public class ChronicDiseaseAdviceService {

    @Autowired
    private ChronicDiseaseMapper chronicDiseaseMapper;

    @Autowired
    private ChronicDiseaseAdviceMapper chronicDiseaseAdviceMapper;

    @Autowired
    private HealthAssistantService healthAssistantService;

    @Autowired
    private UserProfileService userProfileService;

    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    // 获取单个慢性病的日常建议
    public String getDailyAdvice(Integer userId, Integer diseaseId) {
        LocalDate today = LocalDate.now();
        String cached = chronicDiseaseAdviceMapper.findAdvice(userId, "day", today, diseaseId);
        if (cached != null) return cached;

        ChronicDisease disease = chronicDiseaseMapper.findChronicDiseaseById(diseaseId);
        if (disease == null) {
            return "未找到指定的慢性病记录，无法提供建议。";
        }

        // 获取用户基本信息
        UserProfile profile = userProfileService.getUserProfileByUserId(userId);
        if (profile == null) {
            return "未找到用户资料信息，无法提供个性化建议。";
        }

        String prompt = buildDailyPrompt(disease, profile);
        String advice = healthAssistantService.getAnswerFromLLM(prompt);

        chronicDiseaseAdviceMapper.insertAdvice(userId, "day", today, advice, diseaseId);
        return advice;
    }

    // 获取用户所有慢性病的综合日常建议
    public String getComprehensiveDailyAdvice(Integer userId) {
        LocalDate today = LocalDate.now();
        String cached = chronicDiseaseAdviceMapper.findAdvice(userId, "day", today, null);
        if (cached != null) return cached;

        List<ChronicDisease> diseases = chronicDiseaseMapper.findChronicDiseasesByUserId(userId);
        if (diseases == null || diseases.isEmpty()) {
            return "您目前没有记录慢性病信息，无法提供建议。";
        }

        UserProfile profile = userProfileService.getUserProfileByUserId(userId);
        if (profile == null) {
            return "未找到用户资料信息，无法提供个性化建议。";
        }

        String prompt = buildComprehensivePrompt(diseases, profile, "daily");
        String advice = healthAssistantService.getAnswerFromLLM(prompt);

        chronicDiseaseAdviceMapper.insertAdvice(userId, "day", today, advice, null);
        return advice;
    }

    // 获取慢性病的每周建议
    public String getWeeklyAdvice(Integer userId, Integer diseaseId) {
        LocalDate startOfWeek = LocalDate.now().minusDays(LocalDate.now().getDayOfWeek().getValue() - 1);
        String cached = chronicDiseaseAdviceMapper.findAdvice(userId, "week", startOfWeek, diseaseId);
        if (cached != null) return cached;

        ChronicDisease disease = chronicDiseaseMapper.findChronicDiseaseById(diseaseId);
        if (disease == null) {
            return "未找到指定的慢性病记录，无法提供建议。";
        }

        UserProfile profile = userProfileService.getUserProfileByUserId(userId);
        if (profile == null) {
            return "未找到用户资料信息，无法提供个性化建议。";
        }

        // 判断是否有临近的复查时间
        boolean hasUpcomingCheckup = isUpcomingCheckup(disease.getNextCheckupDate());

        String prompt = buildWeeklyPrompt(disease, profile, hasUpcomingCheckup);
        String advice = healthAssistantService.getAnswerFromLLM(prompt);

        chronicDiseaseAdviceMapper.insertAdvice(userId, "week", startOfWeek, advice, diseaseId);
        return advice;
    }

    // 获取所有慢性病的综合每周建议
    public String getComprehensiveWeeklyAdvice(Integer userId) {
        LocalDate startOfWeek = LocalDate.now().minusDays(LocalDate.now().getDayOfWeek().getValue() - 1);
        String cached = chronicDiseaseAdviceMapper.findAdvice(userId, "week", startOfWeek, null);
        if (cached != null) return cached;

        List<ChronicDisease> diseases = chronicDiseaseMapper.findChronicDiseasesByUserId(userId);
        if (diseases == null || diseases.isEmpty()) {
            return "您目前没有记录慢性病信息，无法提供建议。";
        }

        UserProfile profile = userProfileService.getUserProfileByUserId(userId);
        if (profile == null) {
            return "未找到用户资料信息，无法提供个性化建议。";
        }

        String prompt = buildComprehensivePrompt(diseases, profile, "weekly");
        String advice = healthAssistantService.getAnswerFromLLM(prompt);

        chronicDiseaseAdviceMapper.insertAdvice(userId, "week", startOfWeek, advice, null);
        return advice;
    }

    // 获取慢性病的每月建议
    public String getMonthlyAdvice(Integer userId, Integer diseaseId) {
        LocalDate startOfMonth = LocalDate.now().withDayOfMonth(1);
        String cached = chronicDiseaseAdviceMapper.findAdvice(userId, "month", startOfMonth, diseaseId);
        if (cached != null) return cached;

        ChronicDisease disease = chronicDiseaseMapper.findChronicDiseaseById(diseaseId);
        if (disease == null) {
            return "未找到指定的慢性病记录，无法提供建议。";
        }

        UserProfile profile = userProfileService.getUserProfileByUserId(userId);
        if (profile == null) {
            return "未找到用户资料信息，无法提供个性化建议。";
        }

        String prompt = buildMonthlyPrompt(disease, profile);
        String advice = healthAssistantService.getAnswerFromLLM(prompt);

        chronicDiseaseAdviceMapper.insertAdvice(userId, "month", startOfMonth, advice, diseaseId);
        return advice;
    }

    // 获取所有慢性病的综合每月建议
    public String getComprehensiveMonthlyAdvice(Integer userId) {
        LocalDate startOfMonth = LocalDate.now().withDayOfMonth(1);
        String cached = chronicDiseaseAdviceMapper.findAdvice(userId, "month", startOfMonth, null);
        if (cached != null) return cached;

        List<ChronicDisease> diseases = chronicDiseaseMapper.findChronicDiseasesByUserId(userId);
        if (diseases == null || diseases.isEmpty()) {
            return "您目前没有记录慢性病信息，无法提供建议。";
        }

        UserProfile profile = userProfileService.getUserProfileByUserId(userId);
        if (profile == null) {
            return "未找到用户资料信息，无法提供个性化建议。";
        }

        String prompt = buildComprehensivePrompt(diseases, profile, "monthly");
        String advice = healthAssistantService.getAnswerFromLLM(prompt);

        chronicDiseaseAdviceMapper.insertAdvice(userId, "month", startOfMonth, advice, null);
        return advice;
    }

    // 构建单个疾病的日常建议提示词
    private String buildDailyPrompt(ChronicDisease disease, UserProfile profile) {
        StringBuilder sb = new StringBuilder();
        sb.append("请为一位慢性病患者提供今日健康建议。患者信息如下：\n");
        sb.append(String.format("性别：%s，年龄：%d岁，身高：%.1f厘米，体重：%.1f公斤\n",
                profile.getGender(), profile.getAge(), profile.getHeight(), profile.getWeight()));
        sb.append(String.format("慢性病：%s，确诊日期：%s\n",
                disease.getDiseaseName(), formatDate(disease.getDiagnosisDate())));
        sb.append(String.format("当前用药：%s\n", disease.getMedications()));
        sb.append(String.format("管理计划：%s\n", disease.getManagementPlan()));
        sb.append("请提供一份简明、专业的今日健康建议，包括饮食、运动、用药提醒和注意事项。");

        return sb.toString();
    }

    // 构建单个疾病的每周建议提示词
    private String buildWeeklyPrompt(ChronicDisease disease, UserProfile profile, boolean hasUpcomingCheckup) {
        StringBuilder sb = new StringBuilder();
        sb.append("请为一位慢性病患者提供本周健康管理建议。患者信息如下：\n");
        sb.append(String.format("性别：%s，年龄：%d岁，身高：%.1f厘米，体重：%.1f公斤\n",
                profile.getGender(), profile.getAge(), profile.getHeight(), profile.getWeight()));
        sb.append(String.format("慢性病：%s，确诊日期：%s\n",
                disease.getDiseaseName(), formatDate(disease.getDiagnosisDate())));
        sb.append(String.format("当前用药：%s\n", disease.getMedications()));
        sb.append(String.format("管理计划：%s\n", disease.getManagementPlan()));

        if (disease.getLastCheckupDate() != null) {
            sb.append(String.format("上次复查日期：%s\n", formatDate(disease.getLastCheckupDate())));
        }

        if (hasUpcomingCheckup) {
            sb.append(String.format("下次复查日期：%s（即将到来）\n", formatDate(disease.getNextCheckupDate())));
        } else if (disease.getNextCheckupDate() != null) {
            sb.append(String.format("下次复查日期：%s\n", formatDate(disease.getNextCheckupDate())));
        }

        sb.append("请提供一份本周健康管理建议，包括：\n");
        sb.append("1. 饮食调整建议\n");
        sb.append("2. 适合的运动计划\n");
        sb.append("3. 用药管理提醒\n");
        sb.append("4. 生活方式调整建议\n");
        if (hasUpcomingCheckup) {
            sb.append("5. 复查前的注意事项\n");
        }

        return sb.toString();
    }

    // 构建单个疾病的每月建议提示词
    private String buildMonthlyPrompt(ChronicDisease disease, UserProfile profile) {
        StringBuilder sb = new StringBuilder();
        sb.append("请为一位慢性病患者提供本月健康管理综合评估和建议。患者信息如下：\n");
        sb.append(String.format("性别：%s，年龄：%d岁，身高：%.1f厘米，体重：%.1f公斤\n",
                profile.getGender(), profile.getAge(), profile.getHeight(), profile.getWeight()));
        sb.append(String.format("慢性病：%s，确诊日期：%s\n",
                disease.getDiseaseName(), formatDate(disease.getDiagnosisDate())));
        sb.append(String.format("当前用药：%s\n", disease.getMedications()));
        sb.append(String.format("管理计划：%s\n", disease.getManagementPlan()));

        if (disease.getLastCheckupDate() != null) {
            sb.append(String.format("上次复查日期：%s\n", formatDate(disease.getLastCheckupDate())));
        }

        if (disease.getNextCheckupDate() != null) {
            sb.append(String.format("下次复查日期：%s\n", formatDate(disease.getNextCheckupDate())));
        }

        sb.append("请根据患者信息，提供一份本月综合健康管理计划，包括：\n");
        sb.append("1. 月度健康状况评估\n");
        sb.append("2. 长期饮食建议和营养补充\n");
        sb.append("3. 运动规划和适合的锻炼方式\n");
        sb.append("4. 用药管理和潜在副作用监测\n");
        sb.append("5. 生活习惯优化建议\n");
        sb.append("6. 心理健康维护方法\n");

        return sb.toString();
    }

    // 构建综合建议提示词
    private String buildComprehensivePrompt(List<ChronicDisease> diseases, UserProfile profile, String timeFrame) {
        StringBuilder sb = new StringBuilder();
        sb.append(String.format("请为一位多种慢性病患者提供%s健康管理综合建议。患者信息如下：\n",
                timeFrame.equals("daily") ? "今日" :
                        timeFrame.equals("weekly") ? "本周" : "本月"));
        sb.append(String.format("性别：%s，年龄：%d岁，身高：%.1f厘米，体重：%.1f公斤\n",
                profile.getGender(), profile.getAge(), profile.getHeight(), profile.getWeight()));

        sb.append("患者的慢性病情况：\n");
        for (int i = 0; i < diseases.size(); i++) {
            ChronicDisease disease = diseases.get(i);
            sb.append(String.format("%d. %s（确诊日期：%s）\n",
                    i+1, disease.getDiseaseName(), formatDate(disease.getDiagnosisDate())));
            sb.append(String.format("   当前用药：%s\n", disease.getMedications()));

            // 对于每周和每月建议，添加复查信息
            if (!timeFrame.equals("daily")) {
                if (disease.getLastCheckupDate() != null) {
                    sb.append(String.format("   上次复查日期：%s\n", formatDate(disease.getLastCheckupDate())));
                }
                if (disease.getNextCheckupDate() != null) {
                    boolean isUpcoming = isUpcomingCheckup(disease.getNextCheckupDate());
                    sb.append(String.format("   下次复查日期：%s%s\n",
                            formatDate(disease.getNextCheckupDate()),
                            isUpcoming ? "（即将到来）" : ""));
                }
            }
        }

        // 根据时间范围定制提示词
        if (timeFrame.equals("daily")) {
            sb.append("\n请提供一份简明、专业的今日健康综合建议，特别考虑多种慢性病的综合管理，包括：\n");
            sb.append("1. 今日饮食建议（考虑各种疾病的饮食限制和需求）\n");
            sb.append("2. 今日用药提醒和注意事项\n");
            sb.append("3. 适合的活动和运动\n");
            sb.append("4. 需要监测的身体指标\n");
        } else if (timeFrame.equals("weekly")) {
            sb.append("\n请提供一份本周健康管理综合建议，特别考虑多种慢性病的互相影响，包括：\n");
            sb.append("1. 本周饮食计划（平衡各种疾病的饮食需求）\n");
            sb.append("2. 用药管理和可能的相互作用\n");
            sb.append("3. 适合的每周运动安排\n");
            sb.append("4. 生活方式调整建议\n");
            sb.append("5. 需要关注的症状和应对措施\n");
        } else { // monthly
            sb.append("\n请提供一份本月健康管理综合评估和建议，特别关注多种慢性病的长期管理，包括：\n");
            sb.append("1. 月度健康状况评估\n");
            sb.append("2. 长期饮食规划和营养平衡\n");
            sb.append("3. 药物治疗评估和优化建议\n");
            sb.append("4. 运动计划和体能提升策略\n");
            sb.append("5. 生活质量改善措施\n");
            sb.append("6. 心理健康维护方法\n");
            sb.append("7. 社会支持和资源利用建议\n");
        }

        return sb.toString();
    }

    // 检查是否有即将到来的复查
    private boolean isUpcomingCheckup(Date nextCheckupDate) {
        if (nextCheckupDate == null) return false;

        long currentTime = System.currentTimeMillis();
        long checkupTime = nextCheckupDate.getTime();

        // 如果复查时间在两周内，则视为即将到来
        return (checkupTime - currentTime) <= 14 * 24 * 60 * 60 * 1000L
                && checkupTime >= currentTime;
    }

    // 格式化日期
    private String formatDate(Date date) {
        if (date == null) return "未设置";
        return dateFormat.format(date);
    }

    // 清除日常建议缓存
    public void cleanDailyAdviceCache() {
        chronicDiseaseAdviceMapper.deleteAdviceByType("day");
    }

    // 清除指定用户的所有建议缓存
    public void cleanAllUserAdviceCache(Integer userId) {
        chronicDiseaseAdviceMapper.deleteAdviceByUserAndType(userId, "day");
        chronicDiseaseAdviceMapper.deleteAdviceByUserAndType(userId, "week");
        chronicDiseaseAdviceMapper.deleteAdviceByUserAndType(userId, "month");
    }

    // 清除指定用户特定疾病的建议缓存
    public void cleanUserDiseaseAdviceCache(Integer userId, Integer diseaseId) {
        chronicDiseaseAdviceMapper.deleteAdviceByUserDiseaseAndType(userId, diseaseId, "day");
        chronicDiseaseAdviceMapper.deleteAdviceByUserDiseaseAndType(userId, diseaseId, "week");
        chronicDiseaseAdviceMapper.deleteAdviceByUserDiseaseAndType(userId, diseaseId, "month");
    }
}